package com.valuegroup.smarttodo.plugins.pickdialog;

import android.content.Context;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

/**
 * Created by codbking on 2016/12/15.
 */

public class DateUtils {

    public static final String F10 = "yyyy-MM-dd HH:mm:ss";
    public static final String F11 = "yyyy-MM-dd HH:mm";
    public static final String F12 = "yy/M/d";
    public static final String F13 = "MM-dd HH:mm";

    public static final String F20 = "HH:mm:ss";
    public static final String F21 = "HH:mm";
    public static final String F22 = "mm";

    public static final String F30 = "M月dd日";
    public static final String F31 = "M月dd日 EEEE";
    public static final String F32 = "M/dd EEEE";
    public static final String F33 = "M月dd日 EEEE HH:mm";
    public static final String F34 = "MM-dd";

    public static final String F40 = "yyyy-MM-dd";
    public static final String F41 = "yyyyMMdd";
    public static final String F42 = "yyyyMMddHHmmss";
    public static final String F43 = "yyyyMM";

    public static final String F60 = "EEEE"; // 中文星期,"星期一"
    public static final String F61 = "MMMM"; // 中文月份,"十一月"
    public static final String F62 = "w"; // 一年中的第几周,55
    public static final String F63 = "a"; // 上午下午
    public static final String F64 = "EEEE aaHH:mm"; // 中文星期,"星期一 上午9:00"
    public static final String F65 = "aaHH:mm"; // "上午9:00"

    public static final String[] ARR_WEEKS = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};


    //获取小时
    public static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    //获取分钟
    public static int getMinute(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    //当前第几周
    public static int getWeekOfYear(Date date) {
        if (date == null) {
            date = new Date();
        }

        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        //c.setMinimalDaysInFirstWeek(7);
        c.setTime(date);
        return c.get(Calendar.WEEK_OF_YEAR);
    }

    // 获取日期所在周,格式为 201901
    public static int getYearWeekNumber(Date date) {
        return DateUtils.getYear(date) * 100 + getWeekOfYear(date);
    }

    //获取周
    public static int getWeek(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 0 为星期天
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    public static String getWeek2Str(Date date) {
        return ARR_WEEKS[getWeek(date)];
    }

    //获取周
    public static int getWeek(int year, int moth, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, moth - 1, day);
        // 0 为星期天
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }

    // 获取当前时间所在年的最大周数
    public static int getMaxWeekNumOfYear(int year) {

        // 取到指定年份的最后一天
        Date lastDay = getYearLast(year);
        // 算出最後一周
        int weekSize = getWeekOfYear(lastDay);
        // 年末的最後一天有可能是第二年的第一周，如果得到的是第一周則日期逐天往前推
        int moveDay = 1;
        while (weekSize == 1) {
            weekSize = getWeekOfYear(DateUtils.moveDay(lastDay, -moveDay));
            moveDay++;
        }

        return weekSize;
    }


    //获取年
    public static int getYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    //获取月
    public static int getMoth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    // 获取日期所在周,格式为 201904
    public static int getYearQuarterNumber(Date date) {
        return DateUtils.getYear(date) * 100 + getQuarter(date);
    }

    //获取季度
    public static int getQuarter(Date date) {
        int month = getMoth(date);
        switch (month) {
            case 1:
            case 2:
            case 3:
                return 1;
            case 4:
            case 5:
            case 6:
                return 2;
            case 7:
            case 8:
            case 9:
                return 3;
            case 10:
            case 11:
            case 12:
                return 4;
            default:
                return 1;
        }
    }

    //获取日
    public static int getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DATE);
    }

    public static Date getDate(int year, int moth, int day, int hour, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, moth - 1, day, hour, minute, 0);
        return calendar.getTime();
    }


    public static int getScreenWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }

    public static Date moveDay(int offset) {
        return moveDay(new Date(), offset);
    }

    public static Date moveDay(Date date, int offset) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, offset);//把日期往后增加一天.整数往后推,负数往前移动
        return calendar.getTime(); //这个时间就是日期往后推一天的结果
    }

    public static Date setEndTime() {
        return setEndTime(new Date());
    }

    public static Date setEndTime(Date date) {
        return setTime(date, 23, 59, 59, 999);
    }

    public static Date setTime(Date date, int hour, int minute, int second, int milliSecond) {
        Calendar day = new GregorianCalendar();
        day.setTime(date);
        day.set(Calendar.HOUR_OF_DAY, hour);
        day.set(Calendar.MINUTE, minute);
        day.set(Calendar.SECOND, second);
        day.set(Calendar.MILLISECOND, milliSecond);
        return day.getTime();
    }

    public static Date setStartTime() {
        return setStartTime(new Date());
    }

    public static Date setStartTime(Date date) {
        return setTime(date, 0, 0, 0, 0);
    }

    public static Date moveHour(int offset) {
        return moveHour(new Date(), offset);
    }

    public static Date moveHour(Date date, int offset) {
        if (date == null) {
            date = new Date();
        }
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + offset);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime(); //这个时间就是日期往后推一天的结果
    }

    public static Date moveDayAndSetHour(Date date, int dayOffset, int setHour) {
        return setTime(moveDay(date, dayOffset), setHour, 0, 0, 0);
    }

    public static String date2str(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA);
        return format.format(date);
    }

    public static Date str2date(String dateStr, String pattern) {
        if (TextUtils.isEmpty(dateStr)) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA);
        try {
            return format.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取日期是周几
     *
     * @return
     */
    public static String getDay2Week(Date date, int offset) {
        if (date == null) {
            date = new Date();
        }
        if (offset == 0) {
            // 不偏移
            return DateUtils.date2str(date, F60);
        } else {
            return DateUtils.date2str(moveDay(date, offset), F60);
        }
    }

    /**
     * 本周一
     *
     * @param date
     * @return
     */
    public static Date getThisWeekMonday(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        return cal.getTime();
    }

    /**
     * 下周一
     *
     * @param date
     * @return
     */
    public static Date getNextWeekMonday(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(getThisWeekMonday(date));
        cal.add(Calendar.DATE, 7);
        return cal.getTime();
    }

    public static Date getNextWeekMonday() {
        return getNextWeekMonday(new Date());
    }

    /**
     * 上周一
     *
     * @param date
     * @return
     */
    public static Date geLastWeekMonday(Date date) {
        if (date == null) {
            date = new Date();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(getThisWeekMonday(date));
        cal.add(Calendar.DATE, -7);
        return cal.getTime();
    }


    /*根据日期获得所在周的日期*/
    public static List<Date> dateToWeek(Date mdate) {
        int b = mdate.getDay();
        Date fdate;
        List<Date> list = new ArrayList<Date>();
        Long fTime = mdate.getTime() - b * 24 * 3600000;
        for (int a = 1; a <= 7; a++) {
            fdate = new Date();
            fdate.setTime(fTime + (a * 24 * 3600000));
            list.add(a - 1, fdate);
        }
        return list;
    }


    /*根据当前日期获得所在周的日期区间（周一和周日日期）*/
    public static String getTimeInterval(Date date) {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(F40, Locale.CHINA);
        cal.setTime(date);
        // 判断要计算的日期是否是周日，如果是则减一天计算周六的，否则会出问题，计算到下一周去了
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        String imptimeBegin = sdf.format(cal.getTime());
        // System.out.println("所在周星期一的日期：" + imptimeBegin);
        cal.add(Calendar.DATE, 6);
        String imptimeEnd = sdf.format(cal.getTime());
        // System.out.println("所在周星期日的日期：" + imptimeEnd);
        return imptimeBegin + "," + imptimeEnd;
    }

    /*    根据当前日期获得上周的日期区间（上周周一和周日日期）*/
    public String getLastTimeInterval() {
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(F40, Locale.CHINA);

        int dayOfWeek = calendar1.get(Calendar.DAY_OF_WEEK) - 1;
        int offset1 = 1 - dayOfWeek;
        int offset2 = 7 - dayOfWeek;
        calendar1.add(Calendar.DATE, offset1 - 7);
        calendar2.add(Calendar.DATE, offset2 - 7);
        // System.out.println(sdf.format(calendar1.getTime()));// last Monday
        String lastBeginDate = sdf.format(calendar1.getTime());
        // System.out.println(sdf.format(calendar2.getTime()));// last Sunday
        String lastEndDate = sdf.format(calendar2.getTime());
        return lastBeginDate + "," + lastEndDate;
    }

    /*获取一周开始到结束的list集合*/
    public static List<Date> findDates(Date start, Date end) {
        List<Date> result = new ArrayList<>();
        // 加入起始日期
        result.add(start);
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);
        tempStart.add(Calendar.DAY_OF_YEAR, 1);

        // 累加中间日期
        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        while (tempStart.before(tempEnd)) {
            //System.out.println(">>>>>>>>>>>>>>>>>>" + date2str(tempStart.getTime(), F40) + "  before:" + tempStart.before(tempEnd));
            result.add(tempStart.getTime());
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }

        // 加入结束日期
        result.add(end);
        return result;
    }

    public static List<String> dateList2strList(List<Date> dates, String pattern) {
        List<String> resutl = new ArrayList<>();
        for (Date day : dates) {
            resutl.add(date2str(day, pattern));
        }
        return resutl;
    }


    /* 查找日期所在周,一周内的所有日期*/
    public static List<Date> findWeekDayList(Date date) {
        if (date == null) {
            date = new Date();
        }
        String yz_time = getTimeInterval(date);//获取本周时间
        String array[] = yz_time.split(",");
        String start_time = array[0];//本周第一天
        String end_time = array[1];  //本周最后一天
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat(F40, Locale.CHINA);
        Date dBegin = null;
        Date dEnd = null;
        try {
            dBegin = sdf.parse(start_time);
            dEnd = sdf.parse(end_time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return findDates(dBegin, dEnd);//获取这周所有date
    }

    /* 比较日期相等 */
    public static boolean sameDate(Date d1, Date d2) {
        SimpleDateFormat fmt = new SimpleDateFormat(F41, Locale.CHINA);
        return fmt.format(d1).equals(fmt.format(d2));
    }

    /* 比较日期大小(开始时间小于结束时间返回true)
    //返回1:begin大于end;
    //返回0:begin等于end;
    //返回-1:begin小于end
    */
    public static boolean compareDateToBeginLtEnd(Date begin, Date end) {
        SimpleDateFormat fmt = new SimpleDateFormat(F41, Locale.CHINA);
        return fmt.format(begin).compareTo(fmt.format(end)) < 0;
    }

    /* 比较日期大小(开始时间小于结束时间返回true)
    //返回1: a 大于 b;
    //返回0: a 等于 b;
    //返回-1:a 小于 b;
    */
    public static int compareDate(Date a, Date b) {
        SimpleDateFormat fmt = new SimpleDateFormat(F41, Locale.CHINA);
        return fmt.format(a).compareTo(fmt.format(b));
    }

    /* 比较日期大小(开始时间小于结束时间返回true)
    //返回1: a 大于 b;
    //返回0: a 等于 b;
    //返回-1:a 小于 b;
    */
    public static int compareDateAndTime(Date a, Date b) {
        SimpleDateFormat fmt = new SimpleDateFormat(F42, Locale.CHINA);
        return fmt.format(a).compareTo(fmt.format(b));
    }

    /**
     * 计算两个日期相隔天数
     */
    public static int dateInterval(Date begin, Date end) {
        if (begin == null || end == null) {
            return 0;
        }

        Calendar calst = Calendar.getInstance();
        Calendar caled = Calendar.getInstance();
        calst.setTime(begin);
        caled.setTime(end);
        //设置时间为0时
        calst.set(java.util.Calendar.HOUR_OF_DAY, 0);
        calst.set(java.util.Calendar.MINUTE, 0);
        calst.set(java.util.Calendar.SECOND, 0);
        caled.set(java.util.Calendar.HOUR_OF_DAY, 0);
        caled.set(java.util.Calendar.MINUTE, 0);
        caled.set(java.util.Calendar.SECOND, 0);
        //得到两个日期相差的天数
        int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst
                .getTime().getTime() / 1000)) / 3600 / 24;
        return days;
    }


    /**
     * 获取指定年月的第一天
     *
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int year, int month) {
        String monthStr = month < 10 ? "0" + month : String.valueOf(month);
        return year + "-" + monthStr + "-" + "01";
    }

    /**
     * 获取指定年月的最后一天
     *
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, 1);
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) + 1) + "-" +
                calendar.get(Calendar.DAY_OF_MONTH);
    }

    public static Date getLastDayOfMonth2Date(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, 1);
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }

    // 计算指定年份第几周中所有的日期
    public static List<String> getDayListForWeekNum(int year, int weekNum) {
        return dateList2strList(findDates(getStartDayOfWeekNo(year, weekNum), getEndDayOfWeekNo(year, weekNum)), F40);
    }

    // 计算指定年份第几周中所有的日期(201922)
    public static List<Date> getDayListForWeekNum(String yearWeekNum) {
        int year = Integer.parseInt(String.valueOf(yearWeekNum).substring(0, 4));
        int week = Integer.parseInt(String.valueOf(yearWeekNum).substring(4));
        return findDates(getStartDayOfWeekNo(year, week), getEndDayOfWeekNo(year, week));
    }

    // 计算指定年份第几周中周一的日期
    public static Date getStartDayOfWeekNo(int year, int weekNo) {
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.WEEK_OF_YEAR, weekNo);
        return cal.getTime();
    }

    //计算指定年份第几周中周日期的日期
    public static Date getEndDayOfWeekNo(int year, int weekNo) {
        // 得到下周一的时间往前推一天
        return moveDay(getStartDayOfWeekNo(year, weekNo + 1), -1);
    }


    /**
     * 获取当年的第一天
     */
    public static Date getCurrYearFirst() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearFirst(currentYear);
    }

    /**
     * 获取当年的最后一天
     */
    public static Date getCurrYearLast() {
        Calendar currCal = Calendar.getInstance();
        int currentYear = currCal.get(Calendar.YEAR);
        return getYearLast(currentYear);
    }

    /**
     * 获取某年第一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);

        /*Calendar c = Calendar.getInstance();
        c.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
        */
        return calendar.getTime();
    }

    public static Date getYearMonthLast(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        return calendar.getTime();
    }


    public static void main(String[] args) {


        System.out.println(getWeek(moveDay(1)));
/*        for (int i = 1951; i < 1960; i++) {
            System.out.println(date2str(getYearFirst(i), F40));
            System.out.println(date2str(getYearLast(i), F40));
        }

        System.out.println(date2str(getCurrYearFirst(), F40));
        System.out.println(date2str(getCurrYearLast(), F40));

        System.out.println(getLastDayOfMonth(2019,2));
        System.out.println(getLastDayOfMonth(2019,8));
        System.out.println(getLastDayOfMonth(2019,10));*/



        /*int weekNum = 201913;
        int year = Integer.parseInt(String.valueOf(weekNum).substring(0, 4));
        int weekNo = Integer.parseInt(String.valueOf(weekNum).substring(4));
        System.out.println(year);
        System.out.println(weekNo);
       *//* System.out.println("开始时间: " + date2str(getStartDayOfWeekNo(2019, 13), F40));
        System.out.println("结束时间:" + date2str(getEndDayOfWeekNo(2019, 13), F40));
        System.out.println("------");
        System.out.println("开始时间: " + date2str(getStartDayOfWeekNo(2016, 54), F40));
        System.out.println("结束时间:" + date2str(getEndDayOfWeekNo(2016, 54), F40));
        System.out.println("------");
        System.out.println("开始时间: " + date2str(getStartDayOfWeekNo(2017, 1), F40));
        System.out.println("结束时间:" + date2str(getEndDayOfWeekNo(2017, 1), F40));*//*
        Date start = getStartDayOfWeekNo(2019, 13);
        System.out.println(date2str(start, F40));
        Date end = getEndDayOfWeekNo(2019, 13);
        System.out.println(date2str(end, F40));
        System.out.println(dateList2strList(findDates(start, end), F40));*/

    }

}
